Flipping Cookie
You can get a cookie for my website, but it won't help you read the flag... I think.
source.py
from Crypto.Cipher import AES
import os
from Crypto.Util.Padding import pad, unpad
from datetime import datetime, timedelta
KEY = ?
FLAG = ?
@chal.route('/flipping_cookie/check_admin/<cookie>/<iv>/')
def check_admin(cookie, iv):
cookie = bytes.fromhex(cookie)
iv = bytes.fromhex(iv)
try:
cipher = AES.new(KEY, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(cookie)
unpadded = unpad(decrypted, 16)
except ValueError as e:
return {"error": str(e)}
if b"admin=True" in unpadded.split(b";"):
return {"flag": FLAG}
else:
return {"error": "Only admin can read the flag"}
@chal.route('/flipping_cookie/get_cookie/')
def get_cookie():
expires_at = (datetime.today() + timedelta(days=1)).strftime("%s")
cookie = f"admin=False;expiry={expires_at}".encode()
iv = os.urandom(16)
padded = pad(cookie, 16)
cipher = AES.new(KEY, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(padded)
ciphertext = iv.hex() + encrypted.hex()
return {"cookie": ciphertext}
Solution:
Point here to Notice is that the cookie is encrypted with AES CBC mode and the IV is generated randomly. The cookie is also padded with PKCS7 padding. The cookie is decrypted and checked for the string "admin=True". If it is present, the flag is returned.since in CBC mode decrypted message is XOR'd with IV so if we change IV such that the decrypted message is "admin=True" then we can get the flag.
#take two strings with equal length 16 bytes length
xorkey = xorstr(b"admin=False;expr",b"admin=True;expry")
new_iv = xorstr(iv,xorkey)
Complete code for the same is :
import requests
from Crypto.Util.strxor import strxor
url='https://aes.cryptohack.org/flipping_cookie/'
r = requests.get(url+'get_cookie/')
data=r.json()['cookie']
iv=bytes.fromhex(data[:32])
#taking two strings with 16 bytes length
xor_key=strxor(b'admin=False;expi',b'admin=True;expir')
new_iv=strxor(iv,xor_key).hex()
r=requests.get(url+'check_admin/'+data[32:]+'/'+new_iv)
print(r.json()['flag'])
After running following code you will get flag as crypto{4u7h3n71c4710n_15_3553n714l}